Secure access with HTTPS

eXist-db can be accessed via the network via (insecure) HTTP and (secure) HTTPS(see here for SSL configuration ). In release 1.4 HTTPS can simply be enabled by changing a configuration file, while in 1.5/trunk HTTPS is out of the box available via port 8443 (the default HTTP port is 8080).Till until recently the HTTPS port could only easily be used with a webbrowser; starting today (1.5 rev15412 and beyond) it is also usable by the eXist-db Java client and the XMLDB + XMLRPC interfaces.

Read article ...

JFreeChart

Some time ago two interesting articles have been posted about creating dashboards in XQuery. One of the articles makes use of the Google Chart API to render graphs and inspired me to add a charting facility to eXist-db using the JFreeChart library.

sbc3d.png

this article is a reconstruction of an article originally written on 14 april 2009

JFreeChart

Getting Started

The new module is made available as an extension module and is not built by default. To enable the extension perform the following steps:

  • Edit extensions/build.properties and follow the instructions
  • Change include.module.jfreechart = false to true
  • Change include.module.fop = false to true for SVG support (new)
  • Uncomment the module in conf.xml (conf.xml.tmpl)
  • Run build.sh

All required files are downloaded as the module is built. After the build completes the new module's functions are available for use.

How to use

The module provides two functions:

jfreechart:render($a as xs:string, $b as node(), $c as node()) xs:base64Binary?

This function renders the image into a base64 encoded blob, while -

jfreechart:stream-render($a as xs:string, $b as node(), $c as node()) empty()

renders the image directly to the HTTP response (via. the servlet output stream). This function can only be used in the REST interface.

Both functions accept the same set of parameters: a is the chart type, b are the chart settings and c is the chart data.

a : chart type

Not all JFreeChart types are available (yet). At present the following charts are available:

LineChart, LineChart3D, MultiplePieChart, MultiplePieChart3D, PieChart, PieChart3D, RingChart, StackedAreaChart, StackedBarChart, StackedBarChart3D, WaterfallChart.

b : chart settings

Parameters are passed as a node, with the element names reflecting the parameters of the original JFreeChart classes:

ParameterDescription
categoryAxisColor the color of the category axis (#)
categoryAxisLabel the label for the category axis
categoryItemLabelGeneratorClass Set implementing class (see javadoc) (#)
categoryItemLabelGeneratorNumberFormat (see constructors implementing class in javadoc) (#)
categoryItemLabelGeneratorParameter (see constructors implementing class in javadoc) (#)
chartBackgroundColor -
domainAxisLabel the label for the category axis
height Height of chart, default is 300
imageType type of image: "png", "svg" or "svgz"
legend a flag specifying whether or not a legend is required
order the order that the data is extracted; "Column" (default) or "Row"
orientation the plot orientation; "Horizontal" (default) or "Vertical"
pieSectionLabel (see javadoc)
pieSectionNumberFormat (see javadoc)
pieSectionPercentFormat (see javadoc)
plotBackgroundColor (#)
rangeAxisLabel the label for the value axis
rangeLowerBound (#)
rangeUpperBound (#)
sectionColors list of colors, applied sequentially to setSectionPaint (#)
sectionColorsDelimiter delimiter character for sectionColor
seriesColors (#)
tableOrder value "column" or "row" (see javadoc) (#)
timeAxisColor (#)
timeAxisLabel (#)
title the chart title
titleColor (#)
tooltips configure chart to generate tool tips?
urls configure chart to generate URLs?
valueAxisColor (#)
valueAxisLabel the label for the value axis
width Width of chart, default is 400

(#) indicates new added parameters. A small example:

<configuration> <orientation>Horizontal</orientation> <height>500</height> <width>500</width> <title>Example 1</title> </configuration>

c : chart data

Two of the JFreeChart datatypes can be used : CategoryDataset and PieDataset. The module attempts to determine and read the correct Dataset for a graph.

For most of the charts the CategoryDataset is used. The structure of the data is as follows:

<?xml version="1.0" encoding="UTF-8"?> <!-- Sample data for JFreeChart. $Id: categorydata.xml 8835 2009-04-13 19:07:15Z dizzzz $ --> <CategoryDataset> <Series name="Series 1"> <Item> <Key>Category 1</Key> <Value>15.4</Value> </Item> <Item> <Key>Category 2</Key> <Value>12.7</Value> </Item> <Item> <Key>Category 3</Key> <Value>5.7</Value> </Item> <Item> <Key>Category 4</Key> <Value>9.1</Value> </Item> </Series> <Series name="Series 2"> <Item> <Key>Category 1</Key> <Value>45.4</Value> </Item> <Item> <Key>Category 2</Key> <Value>73.7</Value> </Item> <Item> <Key>Category 3</Key> <Value>23.7</Value> </Item> <Item> <Key>Category 4</Key> <Value>19.4</Value> </Item> </Series> </CategoryDataset>

For a subset of charts the PieDataset is used:

<?xml version="1.0" encoding="UTF-8"?> <!-- A sample pie dataset for JFreeChart. $Id: piedata.xml 8835 2009-04-13 19:07:15Z dizzzz $ --> <PieDataset> <Item> <Key>Java</Key> <Value>15.4</Value> </Item> <Item> <Key>C++</Key> <Value>12.7</Value> </Item> <Item> <Key>PHP</Key> <Value>5.7</Value> </Item> <Item> <Key>Python</Key> <Value>9.1</Value> </Item> </PieDataset>

Example

Putting it all together:

categorydata.png
(: Example code for jfreechart module :) (: Load the data files into /db :) (: $Id: categorydata.xq 8838 2009-04-14 18:01:51Z dizzzz $ :) declare namespace jfreechart = "http://exist-db.org/xquery/jfreechart"; jfreechart:stream-render("BarChart", <configuration> <orientation>Horizontal</orientation> <height>300</height> <width>400</width> <title>BarChart Example</title> </configuration>, doc('/db/categorydata.xml'))

and

piedata.png
(: Example code for jfreechart module :) (: Load the data files into /db :) (: $Id: piedata.xq 8838 2009-04-14 18:01:51Z dizzzz $ :) declare namespace jfreechart = "http://exist-db.org/xquery/jfreechart"; jfreechart:stream-render("PieChart", <configuration> <orientation>Horizontal</orientation> <height>300</height> <width>400</width> <title>PieChart Example</title> </configuration>, doc('/db/piedata.xml'))

More info

Todo's

Code is never finished. Although in trunk the code has been reworked, there are always things that could be added....

  • Add more charts
  • Add further Dataset types
  • Make direct use of eXistdb nodes, instead of serializing data first to a data stream and have it parsed by the JFreechart parser. Current solution is multi-threaded though (serialize and parse on 2 separate threads)
  • Add function for showing all supported Graphs
  • Set parameters as provided by JFreeChart.class
  • Transparency etc etc

Tip n Trick: upload and validate XML

I needed to be able to validate an XML document while the document should not be stored in the eXist-db database. The following code snipped shows how to do this

declare namespace util = "http://exist-db.org/xquery/util"; declare namespace validation = "http://exist-db.org/xquery/validation"; (: get file as base64 data from request object :) let $upload := request:get-uploaded-file-data("upload") (: convert base64 to string :) let $text := util:binary-to-string($upload) (: parse into node :) let $parsed := util:parse($text) (: validate :) let $report := validation:jaxv-report($parsed , xs:anyURI('/db/myschema.xsd'))

WebDAV interface revamped

In current trunk (starting 2010-10-01) and in the upcoming 1.4.x release the WebDAV interface has been reimplemented using the Milton WebDAV framework.

The new implementation is considered better (more stable and better clients compatibility) than the original implementation.

The documentation will be updated soon.

Set alternative XML parser

I committed my changes into trunk (1.4!) that enable us to use an alternative XML parser in eXist. I tried the fast Piccolo XML Parser for Java but other JAXP compliant parsers should work as well.

Note that the default Xerces jars must remain in lib/endorsed.

  • download the Piccollo jars from
  • install Picollo.jar into the lib/user directory
  • set the JAVA_OPTIONS system environment: export JAVA_OPTIONS="-Dorg.exist.SAXParserFactory=com.bluecast.xml.JAXPSAXParserFactory"

and start existdb with bin/startup.sh ; in the logging you'll see that then Piccolo parser is actually used.

Need to know

  • When validation is switched on, Piccolo automagically switches to a validating parser: xerces in most cases.

Known issues

  • While loading the mondial example data the mondial dtd is still resolved, resulting in an exception.
  • On quite some code locations SAXParserFactory is called directly. Need to figure out what makes sense to update.